package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
	filepath "path/filepath"
	"strconv"
	"strings"
)

const (
	OUTPUT     = "output"
	NO_CONTENT = iota
	NUMER_FORMAT_ERROR
)

func main() {
	for {
		// fmt.Println(getCurrentDirectory())
		fmt.Println("==================")
		fileList := listAll(".")
		for i := 0; i < len(fileList); i++ {
			fmt.Printf("[%d]%s\n", i, fileList[i])
		}

		fmt.Printf("Step.1 请输入文件序号(%d ~ %d)(空行退出)：\n", 0, len(fileList)-1)
		index, err := getInputNumber()
		if err != nil {
			if err.status == NO_CONTENT {
				break
			} else if err.status == NUMER_FORMAT_ERROR {
				fmt.Println("输入错误，请重新输入")
				continue
			}
		} else {
			if index >= 0 && index < len(fileList) {
				fmt.Printf("你选择了 %s\n", fileList[index])
			} else {
				fmt.Printf("请重新输入\n")
				continue
			}
		}

		fmt.Println("Step.2 需要复制多少份?(空行退出):")
		var num int
		num, err = getInputNumber()
		if err != nil {
			if err.status == NO_CONTENT {
				break
			} else if err.status == NUMER_FORMAT_ERROR {
				continue
			}
		}

		fmt.Println("Step.3 数字从几开始（空行为1）：")
		var start int
		start, err = getInputNumber()
		if err != nil {
			if err.status == NO_CONTENT {
				start = 1
			} else if err.status == NUMER_FORMAT_ERROR {
				continue
			}
		}

		fmt.Println("Step.4 用几位数的0补位（空行为2）：")
		var mask int
		mask, err = getInputNumber()
		if err != nil {
			if err.status == NO_CONTENT {
				mask = 2
			} else if err.status == NUMER_FORMAT_ERROR {
				continue
			}
		}
		root := getCurrentDirectory()
		outputBase := filepath.Join(root, OUTPUT)
		_, fileErr := os.Stat(outputBase)
		if fileErr != nil && os.IsNotExist(fileErr) {
			os.Mkdir(outputBase, os.ModePerm)
		}
		srcFilePath := filepath.Join(root, fileList[index])
		tarFilePath := filepath.Join(outputBase, fileList[index])
		count := 0
		for i := start; i < num+start; i++ {
			count += 1
			copyTo(srcFilePath, tarFilePath, i, mask)
		}
		fmt.Printf("成功复制 %d 个文件\n", count)

	}
}

func copyTo(src string, dist string, seed int, mask int) {
	realNum := strconv.Itoa(seed)
	if mask < strings.Count(realNum, "")-1 {
		mask = strings.Count(realNum, "") - 1
	}
	if mask != 0 {
		tmp := strconv.Itoa(1e6 + seed)
		rs := []rune(tmp)
		length := len(rs)
		realNum = string(rs[length-mask : length])
	}
	dists := []rune(dist)
	// lastPointPos := strings.LastIndex(dist, ".")
	lastPointPos := getDotLastIndex(dist)
	distNamePart1 := string(dists[0:lastPointPos])
	distNamePart2 := string(dists[lastPointPos:])
	dist = strings.Join([]string{distNamePart1, realNum, distNamePart2}, "")
	// fmt.Printf("%s -> %s\n", src, dist)
	copyFile(src, dist)

}

// 找到"."在字符串中的最后一个位置
func getDotLastIndex(all string) int {
	result := -1
	rs := []rune(all)
	dot := rune('.')
	for i := len(rs) - 1; i >= 0; i-- {
		if rs[i] == dot {
			result = i
			break
		}
	}
	return result
}

/**
* 获取用户输入的数字
 */
func getInputNumber() (int, *InputError) {
	var str string
	fmt.Scanln(&str)
	if str == "" {
		return -1, newErr("no content line", NO_CONTENT)
	}
	num, err := strconv.Atoi(str)
	if err != nil {
		return num, newErr("number format err", NUMER_FORMAT_ERROR)
	}
	return num, nil

}

// 获取当前路径
func getCurrentDirectory() string {
	dir, _ := filepath.Abs(filepath.Dir(os.Args[0]))
	return dir
}

func copyFile(src, dst string) (w int64, err error) {
	srcFile, err := os.Open(src)
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	defer srcFile.Close()
	dstFile, err := os.Create(dst)

	if err != nil {
		fmt.Println(err.Error())
		return
	}
	defer dstFile.Close()

	return io.Copy(dstFile, srcFile)
}

/**
 * 遍历文件夹，返回文件名的切片
 */
func listAll(path string) []string {
	files, _ := ioutil.ReadDir(".")
	var list = make([]string, 0, 2)
	for i := 0; i < len(files); i++ {
		if !files[i].IsDir() {
			fileName := files[i].Name()
			list = append(list, fileName)
		}
	}
	return list
}

type InputError struct {
	err    string
	status int
}

func (err *InputError) Error() string {
	return err.err
}

func newErr(s string, status int) *InputError {
	return &InputError{
		err:    s,
		status: status,
	}
}
